import { DevConfig } from './DevConfig';
import { ReactiveProperty } from './../libs/rxjs/cc3/ReactiveProperty';
import { BaseManager } from './../libs/rxjs/cc3/BaseManager';
import { _decorator, color, director, System } from 'cc';
import { fromFetch } from '../libs/rxjs/internal/observable/dom/fetch';
import { Observable, lastValueFrom } from 'rxjs';
import { StageInfo } from './Types';
const { ccclass, property } = _decorator;

const Config = {
    url: 'http://localhost:3000'
}

@ccclass('EditorClientManager')
class EditorClientManager extends BaseManager {
    public static instance: EditorClientManager;
    static ID = 'editor_client_system';
    get logColorOverride() { return color().fromHEX('#CCEEDD') };

    checkPassed = ReactiveProperty.Create(false);

    static registerSystem() {
        director.unregisterSystem(director.getSystem(EditorClientManager.ID));
        director.registerSystem(EditorClientManager.ID, ecm, System.Priority.MEDIUM);
        ecm.init();
    }

    onInitManager() {
        this.log('onInitManager', this.timestamp);
        this.checkServer();
    }

    /**
     * 获取第一关，来测试网络连通性
     */
    async checkServer() {
        if (DevConfig.checkServer) {
            try {
                await lastValueFrom(this.setStage({ stageNum: 0, hi: 100 }));
                await lastValueFrom(this.getStage(0));
            } catch (err) {
                this.warn('checkServer', err);
                this.warn('请检查服务端是否开启,详见:EditorServer/readme.md')
            }
        }
    }

    getStage(stageNumber: number): Observable<StageInfo> {
        return new Observable(observer => {
            fromFetch(`${Config.url}/stage/${stageNumber}`, {
                selector: response => response.json()
            }).subscribe({
                next: _ => {
                    this.log('getStage:', _);
                    this.checkPassed.value = true;
                    observer.next(_);
                    observer.complete();
                },
                error: err => {
                    this.warn('getStage:', err);
                    this.checkPassed.value = false;
                    observer.error(err);
                }
            });
        })
    }

    setStage(data: object) {
        return new Observable(observer => {
            fromFetch(`${Config.url}/stage`, {
                method: 'POST',
                body: JSON.stringify(data),
                headers: {
                    'Content-Type': 'application/json'
                },
                selector: response => response.json()
            }).subscribe({
                next: _ => {
                    this.log('setStage:', _);
                    this.checkPassed.value = true;
                    observer.next(_);
                    observer.complete();
                },
                error: err => {
                    this.warn('setStage:', err);
                    this.checkPassed.value = false;
                    observer.error(err);
                }
            });
        })
    }
}

globalThis.EditorClientManager = EditorClientManager;

export const ecm = EditorClientManager.instance = new EditorClientManager();


